part of '../shelf.dart';

const String _keyBody = "raw_body";

/// 从输入中读取body，并加载为json格式，然后注入到context中
/// 期间如果发生什么问题，则会直接返回给客户端错误信息
Middleware getBody = (Handler inner) => (Request request) async {
      // 从request中读取body内容
      final String bodyStr = await request.readAsString();
      // 将内容解析为json，如果错误，则注入错误信息，并继续处理
      dynamic json;
      late final Request newRequest;
      try {
        json = jsonDecode(bodyStr);
      } catch (e) {
        newRequest =
            request.change(context: {_keyBody: Bug("无法将body解析为有效的json格式")});
        return inner(newRequest);
      }

      // 解析出来的json如果不是Map格式，则注入错误信息
      if (json is! Json) {
        newRequest =
            request.change(context: {_keyBody: Bug("json解析后不是JsonMap格式")});
      } else {
        // 一切解析正常时，将数据注入到context中
        newRequest = request.change(context: {_keyBody: json});
      }

      // 返回注入过的请求
      return inner(newRequest);
    };

extension ReadRawBody on Request {
  // 如果客户端上传信息，那么必然是一个个的，而不是一堆
  // 因此目前直接将它解析为Map格式即可
  Json get body {
    // 根本没有这个key，则代表没有调用过中间件
    if (!context.containsKey(_keyBody)) throw Bug("在获取body之前，需要先调用getBody中间件");
    // 如果value为字符串，则是调用的过程中产生错误，此时里面的String为错误信息，需要报错
    if (context[_keyBody] is Bug) throw context[_keyBody]!;
    return context[_keyBody] as Json;
  }
}
